#!/bin/bash

# Kubernetes集群自动化配置脚本
# 在虚拟机中运行此脚本来配置K8s环境

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查是否为root用户
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "此脚本需要root权限运行"
        exit 1
    fi
}

# 配置系统环境
setup_system() {
    log_info "配置系统环境..."
    
    # 关闭防火墙
    systemctl disable firewalld --now 2>/dev/null || true
    
    # 关闭SELinux
    setenforce 0 2>/dev/null || true
    sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
    
    # 关闭swap
    swapoff -a
    sed -i '/swap/d' /etc/fstab
    
    # 配置内核参数
    cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
    
    # 加载br_netfilter模块
    modprobe br_netfilter
    echo 'br_netfilter' > /etc/modules-load.d/k8s.conf
    
    # 应用内核参数
    sysctl --system
    
    log_success "系统环境配置完成"
}

# 安装Docker
install_docker() {
    log_info "安装Docker..."
    
    # 安装依赖
    yum install -y yum-utils device-mapper-persistent-data lvm2
    
    # 添加Docker仓库
    yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    
    # 安装Docker
    yum install -y docker-ce docker-ce-cli containerd.io
    
    # 配置Docker
    mkdir -p /etc/docker
    cat > /etc/docker/daemon.json << EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com"
  ]
}
EOF
    
    # 启动Docker
    systemctl enable docker --now
    
    log_success "Docker安装完成"
}

# 安装Kubernetes
install_kubernetes() {
    log_info "安装Kubernetes..."
    
    # 添加K8s仓库
    cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
    
    # 安装kubelet、kubeadm、kubectl
    yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
    
    # 启用kubelet
    systemctl enable kubelet
    
    log_success "Kubernetes安装完成"
}

# 配置主节点
setup_master() {
    local node_ip=$1
    log_info "配置Kubernetes主节点..."
    
    # 初始化集群
    kubeadm init \
        --apiserver-advertise-address=$node_ip \
        --pod-network-cidr=10.244.0.0/16 \
        --service-cidr=10.96.0.0/12 \
        --image-repository=registry.aliyuncs.com/google_containers
    
    # 配置kubectl
    mkdir -p $HOME/.kube
    cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    chown $(id -u):$(id -g) $HOME/.kube/config
    
    # 安装Flannel网络插件
    kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
    
    # 生成加入集群的命令
    kubeadm token create --print-join-command > /tmp/k8s-join-command.sh
    chmod +x /tmp/k8s-join-command.sh
    
    log_success "主节点配置完成"
    log_info "工作节点加入命令已保存到 /tmp/k8s-join-command.sh"
}

# 配置工作节点
setup_worker() {
    local master_ip=$1
    local join_command=$2
    
    log_info "配置Kubernetes工作节点..."
    
    if [[ -n "$join_command" ]]; then
        # 执行加入命令
        eval $join_command
        log_success "工作节点已加入集群"
    else
        log_warning "请手动执行主节点生成的加入命令"
        log_info "或从主节点复制 /tmp/k8s-join-command.sh 文件并执行"
    fi
}

# 显示集群状态
show_cluster_status() {
    log_info "集群状态:"
    kubectl get nodes -o wide
    echo
    kubectl get pods -A
}

# 主函数
main() {
    local node_type=${1:-""}
    local node_ip=${2:-""}
    local join_command=${3:-""}
    
    if [[ -z "$node_type" || -z "$node_ip" ]]; then
        echo "使用方法:"
        echo "  配置主节点: $0 master <节点IP>"
        echo "  配置工作节点: $0 worker <节点IP> [加入命令]"
        echo
        echo "示例:"
        echo "  $0 master 192.168.100.10"
        echo "  $0 worker 192.168.100.11 'kubeadm join ...'"
        exit 1
    fi
    
    check_root
    
    log_info "开始配置Kubernetes $node_type 节点 (IP: $node_ip)"
    
    # 基础环境配置
    setup_system
    install_docker
    install_kubernetes
    
    # 根据节点类型进行配置
    case $node_type in
        "master")
            setup_master $node_ip
            show_cluster_status
            ;;
        "worker")
            setup_worker $node_ip "$join_command"
            ;;
        *)
            log_error "未知的节点类型: $node_type"
            exit 1
            ;;
    esac
    
    log_success "Kubernetes $node_type 节点配置完成!"
}

# 执行主函数
main "$@"